/*
 * =====================================================================================
 *
 *       Filename:  messageHandle.hpp
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  2009-3-3 10:05:59
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Fang Dongheng (fndisme), fndisme@163.com
 *        Company:  Artcoding, Shanghai, China
 *
 * =====================================================================================
 */
#ifndef FND_GAME_OT2_MESSAGEHANDLE_H_
#define FND_GAME_OT2_MESSAGEHANDLE_H_
#include <map>
#include <cassert>
#include <stdexcept>
#include <boost/bind.hpp>
#include <boost/function.hpp>

namespace Utility {
  template<typename Key, typename FuncParam>
    class message_manager {
      public:
        typedef message_manager<Key, FuncParam>   class_type ;
        typedef Key                             key_type ;
        typedef FuncParam                       function_para_type ;
        typedef FuncParam*                      function_para_pointer ;
      public:
        typedef boost::function<void (function_para_type)> function_type ;
        typedef std::map<key_type, function_type > HandleMap ;

        void add(const key_type& k, function_type func) {
          handleMap.insert(std::make_pair(k, func)) ;
        }
        template<typename T>
        void add(const key_type& k, T* obj,
            void(T::*func)(function_para_type)) {
          assert(obj) ;
          if(!obj) {
            throw std::runtime_error("pointer is not valid") ;
          }
          this->add(k, boost::bind(boost::mem_fn(func), obj, _1)) ;
        }

        void deal_with_message(const key_type& k, function_para_type param) {
          
            if(is_registered(k)) {
              (handleMap[k])(param) ;
          }
          
        }

        bool is_registered(const key_type& k) {
            return handleMap.count(k) != 0 ;
        }

        void remove(const key_type& k) {
          handleMap.erase(k) ;
        }

      private:
        HandleMap handleMap ;
    } ;
}
#endif

